<template>
  <div class="role">
    <!-- 上半部分 -->
    <el-card class="box-card">
      <el-form :inline="true" style="display:flex;justify-content: space-between;align-item:center">
        <el-form-item label="角色名称">
          <el-input v-model="searchInput" type="text" placeholder="角色名称"></el-input>
        </el-form-item>
        <el-form-item >
          <el-button type="primary" :disabled="searchInput == ''" @click="search_btn">搜索</el-button>
          <el-button @click="reset_btn">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 下半部分 -->
    <el-card class="box-card" style="margin:15px 0;">
      <!-- 按钮部分 -->
      <el-button type="primary" icon="plus" @click="addRole" v-has="`btn.Roal.add`">添加角色</el-button>
      <!-- 表格部分 -->
      <el-table :data="roleInfoList" border style="margin:15px 0;">
        <el-table-column label="#" type="index" width="60"></el-table-column>
        <el-table-column prop="id" label="id" width="80"></el-table-column>
        <el-table-column prop="roleName" label="角色名称" width="150"></el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="200"></el-table-column>
        <el-table-column prop="updateTime" label="更新时间" width="200"></el-table-column>
        <el-table-column label="操作">
          <template #="{row,$index}">
            <el-button type="primary" size="small" icon="User" @click="distributePermission_btn(row)">分配权限</el-button>
            <el-button type="success" size="small" icon="edit" @click="edit_btn(row)">编辑</el-button> 
            <el-popconfirm :title="`确定删除角色${row.roleName}吗?`" @confirm="delete_btn(row)">
              <template #reference>
                <el-button type="danger" size="small" icon="delete">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器部分 -->
      <el-pagination :current-page="paging.pageNo" :page-size="paging.pageSize" :total="paging.total" background layout="prev, pager, next, jumper, ->, sizes, total" :page-sizes="[3,5,7,9,15,30]" @current-change="handlerCurrent" @size-change="handlerSize" />
    </el-card>
    <!-- 添加或修改角色的dialog框 -->
    <el-dialog v-model="dialogSwitch" @close="dialog_cancel_btn" :title="addOrEditRole.id == undefined?'添加角色':'修改角色'">
      <el-form :model="addOrEditRole">
        <el-form-item label="角色名称" label-width="100px">
          <el-input type="text" v-model="addOrEditRole.roleName" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialog_cancel_btn">取消</el-button>
          <el-button type="primary" @click="dialog_confirm_btn">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 为角色分配权限的drawer抽屉弹框 -->
    <el-drawer v-model="drawerSwitch" title="分配权限">
      <template #default>
        <!-- 树型控件 -->
        <el-tree :data="rolePermissionInfo" @check="checkHandler" ref="treeRef" :default-checked-keys="defaultPermission" :default-expanded-keys="defaultPermission" show-checkbox node-key="id" :props="defaultProps"/>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="drawer_btn_cancel">取消</el-button>
          <el-button type="primary" @click="drawer_btn_confirm">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ElCard, ElInput, ElButton, ElTable, ElTableColumn, ElPagination, ElMessage, ElDialog, ElDrawer, ElForm, ElFormItem, ElPopconfirm, ElTree } from "element-plus";
import { User } from '@element-plus/icons-vue';
//@ts-ignore,引入请求函数
import { reqRoleInfo, reqAddRole, reqUpdateRole, reqDeleteRole, reqRolePermissionInfo, reqDistributePermission } from "@/api/permission/index.ts";
//@ts-ignore,引入类型约束
import {  } from "@/api/permission/type.ts";
import { onMounted, reactive, ref } from "vue";

//角色信息列表数据
let roleInfoList = ref([]);
//搜索框，搜索角色名称
let searchInput = ref("");
//添加，修改角色名称收集
let addOrEditRole = reactive<any>({
  roleName:"",
})
//添加或修改角色的dialog对话框开关
let dialogSwitch = ref(false);
//为角色分配权限的drawer抽屉开关
let drawerSwitch = ref(false);
//当前角色的权限信息
let rolePermissionInfo = ref([]);

//树型控件数据
let treeRef = ref();
const defaultProps = {
  children: 'children',
  label: 'name',
}
//初始选中的权限ids
let defaultPermission = ref([]);
//选择的权限按钮ids(需要作为请求参数)
let selectedIds = [];
let roleId = 0;  //需要给哪个角色分配权限的角色id,需要作为请求参数

//分页器部分数据
let paging = reactive({
  pageNo:1,
  pageSize:3,
  total:0
})

//生命周期
onMounted(()=>{
  //发请求
  getRoleInfo();
})

//请求函数，获取所有角色信息
const getRoleInfo = async () => {
  let res:any = await reqRoleInfo(paging.pageNo,paging.pageSize);
  if(res.code == 200){
    ElMessage({type:"success",message:"角色信息获取成功!"});
    roleInfoList.value = res.data.records;
    paging.total = res.data.total;
    // console.log("角色信息api成功",res);
  }
}

//上部分的搜索、重置按钮
const search_btn = async () => {
  paging.pageNo = 1;
  let res:any = await reqRoleInfo(paging.pageNo,paging.pageSize,{roleName:searchInput.value});
  if(res.code == 200){
    roleInfoList.value = res.data.records;
    ElMessage({type:"success",message:"角色搜索成功!"});
    searchInput.value = "";
    // console.log("搜索角色api成功",res);
  }
}
const reset_btn = () => {
  //调用window提供方法，进行重新加载页面
  window.location.reload();
}

//添加角色按钮
const addRole = () => {
  //打开dialog对话框
  dialogSwitch.value = true;
}

//表格中的分配权限、编辑、删除按钮
const edit_btn = (row) => {
  //获取修改角色信息
  addOrEditRole = row;
  //打开dialog
  dialogSwitch.value = true;
}
const distributePermission_btn = async (row) => {
  //发请求获取当前角色权限信息
  let res:any = await reqRolePermissionInfo(row.id);
  if(res.code == 200){
    rolePermissionInfo.value = res.data;
    let arr = [];
    defaultPermission.value = dealSelectedPermission(res.data, arr);
    selectedIds = arr;  //收集参数一份
    roleId = row.id;  //收集参数角色id
    // console.log("角色权限信息api成功",res);
  }
  //打开drawer
  drawerSwitch.value = true;
}
const delete_btn = async (row) => {
  let res:any = await reqDeleteRole(row.id);
  if(res.code == 200){
    //重发请求，更新角色列表
    getRoleInfo();
    ElMessage({type:"success",message:"角色删除成功!"});
    // console.log("删除角色api成功",res);
  }
}

//dialog中的确定与取消按钮
const dialog_confirm_btn = async () => {
  //发请求更新数据
  if(addOrEditRole.id == undefined){
    //添加角色
    let res:any = await reqAddRole(addOrEditRole);
    if(res.code == 200){
      //重发请求更新数据
      getRoleInfo();
      //发送通知
      ElMessage({type:"success",message:"角色添加成功"});
      // console.log("添加或修改角色api成功",res);
    }
  } else {
    //修改角色
    let res:any = await reqUpdateRole(addOrEditRole);
    if(res.code == 200){
      //重发请求更新数据
      getRoleInfo();
      //发送通知
      ElMessage({type:"success",message:"角色更新成功"});
      // console.log("添加或修改角色api成功",res);
    }
  }
  //调用关闭按钮
  dialog_cancel_btn();
}
const dialog_cancel_btn = () => {
  //置空数据
  addOrEditRole = {roleName:""};
  //关闭dialog
  dialogSwitch.value = false;
}
//drawer中的确定与取消按钮
const drawer_btn_confirm = async () => {
  //发请求
  let res:any = await reqDistributePermission(selectedIds,roleId);
  if(res.code == 200){
    drawer_btn_cancel();
    ElMessage({type:"success",message:"权限分配成功!"});
    // console.log("给角色分配权限api成功",res);
  }
  //调用关闭按钮
  // drawer_btn_cancel();
}
const drawer_btn_cancel = () => {
  //置空数据
  defaultPermission.value = [];
  selectedIds = [];
  roleId = 0;
  //关闭drawer
  drawerSwitch.value = false;
}
//树型控件的复选框事件
//currentNode:当前选中节点信息包含子节点，nodeInfo:选中的node节点及其子节点的id值
const checkHandler = (currentNode:any,nodeInfo:any) => {
  selectedIds = nodeInfo.checkedKeys;  //给参数赋值
}
//失败的工具函数,过滤出取消选中的id,(人家elementPlus提供了相关功能，白瞎一个下午琢磨树型控件，各种判断，递归，诶...)
function filterIds(arr:any,delArr:any){
  for(let i=0; i<arr.length; i++){
    delArr.push(arr[i].id);
    if(arr[i].children && arr[i].children.length !== 0){
      filterIds(arr[i].children,delArr);
    }
  }
  return delArr;
}
//失败的工具函数
function deal (permissionInfo,NodeInfo:any){
  for(let i=0; i<permissionInfo.length; i++){
    if(permissionInfo[i].id == NodeInfo.node.id){
      //进行处理
      if(NodeInfo.isChecked == true){
        permissionInfo[i].select = true;
        //将子节点的select属性设为true
        function settingSelected(){
          if(permissionInfo[i].children && permissionInfo[i].children.length !== 0){
            for(let j=0; j<permissionInfo[i].children; j++){
              permissionInfo[i].children[j].select = true;
              if(permissionInfo[i].children[j].children && permissionInfo[i].children[j].children.length !== 0){
                settingSelected();
              }
            }
          }
        }
        settingSelected();
      } else if(NodeInfo.childrenHasChecked){
        //当前节点没选中，但是子节点有选中的，继续进行遍历
        return ;
      } else {
        //都没有选中的，不需要进行操作
        return ;
      }
    } else {
      if(permissionInfo[i].children && permissionInfo[i].children.length !== 0){
        deal(permissionInfo[i].children,NodeInfo);
      }
    }
  }
}

//分页器相关回调函数
const handlerCurrent = (currentPage:number) => {
  paging.pageNo = currentPage;
  //重发请求获取所有角色信息
  getRoleInfo();
}
const handlerSize = (pageSize:number) => {
  paging.pageSize = pageSize;
  //重发请求获取所有角色信息
  getRoleInfo();
}

//功能函数，处理初始选中的权限id值，存储在一个数组中，供树型控件使用
function dealSelectedPermission (dealArr:any, arr:any) {
  for(let i=0; i<dealArr.length; i++){
    if(dealArr[i].select && dealArr[i].select == true){
      arr.push(dealArr[i].id);
      if(dealArr[i].children && dealArr[i].children.length !== 0){
        dealSelectedPermission(dealArr[i].children, arr);
      }
    } else {
      if(dealArr[i].children.length !== 0){
        dealSelectedPermission(dealArr[i].children, arr);
      }
    }
  }
  return arr;
}

</script>
<script lang="ts">
export default {
  name:"Role"
}
</script>

<style>

</style>